package com.zp.common.base.service.impl;

import com.zp.common.base.dao.*;
import com.zp.common.base.entity.RoleAuth;
import com.zp.common.base.entity.SecurityUser;
import com.zp.common.base.entity.User;
import com.zp.common.base.entity.UserRole;
import com.zp.common.base.service.LoginService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import static com.zp.common.base.constant.Atom.CONSTANT_ONE;

/**
 * 登录服务impl,实现UserDetailsService
 * security的整个认证流程会通过UserDetailsService的实现类来获取用户，这里我们实现它
 *
 * @author zp
 */

@Service
@RequiredArgsConstructor
public class LoginServiceImpl implements LoginService, UserDetailsService {

    private final UserRepository userRepository;
    private final UserRoleRepository userRoleRepository;
    private final RoleAuthRepository roleAuthRepository;
    private final RoleRepository roleRepository;
    private final AuthRepository authRepository;


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //获取用户信息
        User user = userRepository.findByUsernameAndStatus(username,CONSTANT_ONE);
        SecurityUser securityUser=null;
        if (Objects.nonNull(user)){
            securityUser = new SecurityUser();
            securityUser.setUsername(username);
            securityUser.setPassword(user.getPassword());
            securityUser.setTelephone(user.getTelephone());
            securityUser.setEmail(user.getEmail());
            //查询该用户的角色
            List<UserRole> userRoles = userRoleRepository.findByUserIdAndStatus(user.getUserId(),CONSTANT_ONE);
            //获取权限集合
            Collection<? extends GrantedAuthority> authorities = merge(userRoles);
            securityUser.setAuthorities(authorities);
        }
        //从数据库中查询
        //用户不存在直接抛出UsernameNotFoundException，security会捕获抛出BadCredentialsException
        if (Objects.isNull(securityUser))
            throw new UsernameNotFoundException("用户不存在！");
        return securityUser;
    }

    /**
     * 查询角色
     */
    private List<String> listRoles(List<UserRole> userRoles){
        List<String> list=new ArrayList<>();
        if (!CollectionUtils.isEmpty(userRoles)){
            userRoles.forEach(param-> list.add(roleRepository
                    .selectById(param.getRoleId()).getName())
            );
        }
        return list;
    }

    /**
     * 查询权限
     */
    private List<String> listAuths(List<UserRole> userRoles){
        List<String> list=new ArrayList<>();
        if (!CollectionUtils.isEmpty(userRoles)){
            userRoles.forEach(param->{
                List<RoleAuth> roleAuths = roleAuthRepository.findByRoleIdAndStatus(param.getRoleId(), CONSTANT_ONE);
                //查询权限
                if (!CollectionUtils.isEmpty(roleAuths)){
                    roleAuths.forEach(o-> list.add(authRepository
                            .selectById(o.getAuthId())
                            .getName()));
                }
            });
        }
        return list;
    }

    private Collection<? extends GrantedAuthority> merge(List<UserRole> userRoles){
        List<String> roles = listRoles(userRoles);
        List<String> auths = listAuths(userRoles);
        String[] a={};
        roles.addAll(auths);
        return AuthorityUtils.createAuthorityList(roles.toArray(a));
    }
}
